package ebedynky.editors;

import ebedynky.services.*;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Set;
import java.util.logging.*;
import java.util.regex.Pattern;
import org.springframework.beans.propertyeditors.*;

/**
 * @author Ondrej David (davidon1)
 */
public class EditorFactory {

    /**
     * ClassEditor for converting productCategoryID to ProductCategory (fetch ProductCategory by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getCategoryIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    ProductCategoryService cs = new ProductCategoryService();
                    int id = Integer.parseInt(text);
                    super.setValue(cs.getProductCategoryByID(id));
                    cs.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: ProductCategoryService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting productGenusID to ProductGenus (fetch ProductGenus by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getGenusIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    ProductGenusService gs = new ProductGenusService();
                    int id = Integer.parseInt(text);
                    super.setValue(gs.getProductGenusByID(id));
                    gs.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: ProductGenusService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting productSpecificationID to ProductSpecification (fetch ProductSpecification by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getSpecificationIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    ProductSpecificationService ss = new ProductSpecificationService();
                    int id = Integer.parseInt(text);
                    super.setValue(ss.getProductSpecificationByID(id));
                    ss.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: ProductSpecificationService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting productID to Product (fetch Product by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getProductIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    ProductService ps = new ProductService();
                    int id = Integer.parseInt(text);
                    super.setValue(ps.getProductByID(id));
                    ps.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: ProductService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting userID to Customer (fetch Customer by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getCustomerIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    CustomerService cs = new CustomerService();
                    int id = Integer.parseInt(text);
                    super.setValue(cs.getCustomerByID(id));
                    cs.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: CustomerService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting userID to Supplier (fetch Supplier by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getSupplierIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    SupplierService ss = new SupplierService();
                    int id = Integer.parseInt(text);
                    super.setValue(ss.getSupplierByID(id));
                    ss.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: SupplierService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting userIDs to Set<Supplier> (fetch Suppliers by ids from db).
     * @return CustomCollectionEditor for conversion.
     * @throws Exception on Service error.
     */
    public static CustomCollectionEditor getSupplierIDtoSetEditor() throws Exception {
        return (new CustomCollectionEditor(Set.class) {

            private SupplierService ss = new SupplierService();

            @Override
            protected Object convertElement(Object element) {
                try {
                    int id = 0;
                    if (element instanceof String) {
                        id = Integer.parseInt((String) element);
                    }
                    return ss.getSupplierByID(id);
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: SupplierService conversion error", ex);
                }
                return null;
            }

            @Override
            protected void finalize() throws Throwable {
                ss.close();
                super.finalize();
            }
        });
    }

    /**
     * ClassEditor for converting deliveryPlaceID to DeliveryPlace (fetch DeliveryPlace by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getDeliveryPlaceIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    DeliveryPlaceService ps = new DeliveryPlaceService();
                    int id = Integer.parseInt(text);
                    super.setValue(ps.getDeliveryPlaceByID(id));
                    ps.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: DeliveryPlaceService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting offerID to Offer (fetch Offer by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getOfferIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    OfferService os = new OfferService();
                    int id = Integer.parseInt(text);
                    super.setValue(os.getOfferByID(id));
                    os.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: OfferService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting offerIDs to Set<Offer> (fetch Offers by ids from db).
     * @return CustomCollectionEditor for conversion.
     * @throws Exception on Service error.
     */
    public static CustomCollectionEditor getOfferIDtoSetEditor() throws Exception {
        return (new CustomCollectionEditor(Set.class) {

            private OfferItemService ois = new OfferItemService();

            @Override
            protected Object convertElement(Object element) {
                try {
                    int id = 0;
                    if (element instanceof String) {
                        id = Integer.parseInt((String) element);
                    }
                    return ois.getOfferItemByID(id);
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: OfferItemService conversion error", ex);
                }
                return null;
            }

            @Override
            protected void finalize() throws Throwable {
                ois.close();
                super.finalize();
            }
        });
    }

    /**
     * ClassEditor for converting boxIDs to Set<Box> (fetch Boxes by ids from db).
     * @return CustomCollectionEditor for conversion.
     * @throws Exception on Service error.
     */
    public static CustomCollectionEditor getBoxIDtoSetEditor() throws Exception {
        return (new CustomCollectionEditor(Set.class) {

            private BoxService bs = new BoxService();

            @Override
            protected Object convertElement(Object element) {
                try {
                    int id = 0;
                    if (element instanceof String) {
                        id = Integer.parseInt((String) element);
                    }
                    return bs.getBoxByID(id);
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: BoxService conversion error", ex);
                }
                return null;
            }

            @Override
            protected void finalize() throws Throwable {
                bs.close();
                super.finalize();
            }
        });
    }

    /**
     * ClassEditor for converting boxOrderID to BoxOrder (fetch BoxOrder by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getBoxOrderIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    BoxOrderService bos = new BoxOrderService();
                    int id = Integer.parseInt(text);
                    super.setValue(bos.getBoxOrderByID(id));
                    bos.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: BoxOrderService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting boxOrderIDs to Set<BoxOrder> (fetch BoxOrders by ids from db).
     * @return CustomCollectionEditor for conversion.
     * @throws Exception on Service error.
     */
    public static CustomCollectionEditor getBoxOrderIDtoSetEditor() throws Exception {
        return (new CustomCollectionEditor(Set.class) {

            private BoxOrderService bos = new BoxOrderService();

            @Override
            protected Object convertElement(Object element) {
                try {
                    int id = 0;
                    if (element instanceof String) {
                        id = Integer.parseInt((String) element);
                    }
                    return bos.getBoxOrderByID(id);
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: BoxorderService conversion error", ex);
                }
                return null;
            }

            @Override
            protected void finalize() throws Throwable {
                bos.close();
                super.finalize();
            }
        });
    }

    /**
     * ClassEditor for converting offerItemID to OfferItem (fetch OfferItem by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getOfferItemIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    OfferItemService ois = new OfferItemService();
                    int id = Integer.parseInt(text);
                    super.setValue(ois.getOfferItemByID(id));
                    ois.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: OfferItemService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting offerItemIDs to Set<OfferItem> (fetch OfferItems by ids from db).
     * @return CustomCollectionEditor for conversion.
     * @throws Exception on Service error.
     */
    public static CustomCollectionEditor getOfferItemIDtoSetEditor() throws Exception {
        return (new CustomCollectionEditor(Set.class) {

            private OfferItemService ois = new OfferItemService();

            @Override
            protected Object convertElement(Object element) {
                try {
                    int id = 0;
                    if (element instanceof String) {
                        id = Integer.parseInt((String) element);
                    }
                    return ois.getOfferItemByID(id);
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: OfferItemService conversion error", ex);
                }
                return null;
            }

            @Override
            protected void finalize() throws Throwable {
                ois.close();
                super.finalize();
            }
        });
    }

    /**
     * ClassEditor for converting orderItemID to OrderItem (fetch OrderItem by id from db).
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getOrderItemIDEditor() {
        return (new ClassEditor() {

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    OrderItemService ois = new OrderItemService();
                    int id = Integer.parseInt(text);
                    super.setValue(ois.getOrderItemByID(id));
                    ois.close();
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: OrderItemService conversion error", ex);
                }
            }
        });
    }

    /**
     * ClassEditor for converting orderItemIDs to Set<OrderItem> (fetch OrderItems by ids from db).
     * @return CustomCollectionEditor for conversion.
     * @throws Exception on Service error.
     */
    public static CustomCollectionEditor getOrderItemIDtoSetEditor() throws Exception {
        return (new CustomCollectionEditor(Set.class) {

            private OrderItemService ois = new OrderItemService();

            @Override
            protected Object convertElement(Object element) {
                try {
                    int id = 0;
                    if (element instanceof String) {
                        id = Integer.parseInt((String) element);
                    }
                    return ois.getOrderItemByID(id);
                } catch (Exception ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: OrderItemService conversion error", ex);
                }
                return null;
            }

            @Override
            protected void finalize() throws Throwable {
                ois.close();
                super.finalize();
            }
        });
    }

    /**
     * ClassEditor for converting String to Timestamp.
     * @return ClassEditor for conversion.
     */
    public static ClassEditor getTimestampFromStringEditor() {
        return (new ClassEditor() {

            @Override
            public String getAsText() {
                if (super.getValue() != null) {
                    return DateFormat.getDateInstance().format((Timestamp) super.getValue());
                }
                return super.getAsText();
            }

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                try {
                    Timestamp t = new Timestamp(DateFormat.getDateInstance().parse(text).getTime());
                    super.setValue(t);
                } catch (ParseException ex) {
                    Logger.getLogger(EditorFactory.class.getName()).log(Level.SEVERE, "EditorFactory: Date conversion error", ex);
                }
            }
        });
    }

    /**
     * Validates the source string against the RegExp pattern.
     * @param source to be validated.
     * @param regexpPattern RegExp valdation pattern. For more info see: @see http://www.regular-expressions.info/ .
     * @return true if matches, false otherwise.
     */
    public static boolean matches(String source, String regexpPattern) {
        return Pattern.compile(regexpPattern).matcher(source).matches();
    }
}
